Table of Contents
In the last tutorial, we looked at textures that were not pictures. Now, we will look at textures that are pictures. However, unlike the last tutorial, where the textures represented some parameter in the light equation, here, we will just be directly outputting the values read from the texture.
We will start by drawing a single large, flat plane. The plane will have a texture of a checkerboard drawn on it. The camera will hover above the plane, looking out at the horizon as if the plane were the ground. This is implemented in the Many Images tutorial project.
The camera is automatically controlled, though it's motion can be paused with the P key. The other functions of the tutorial will be explained as we get to them.
If you look at the BigPlane.xml
file, you will find that the
texture coordinates are well outside of the [0, 1] range we are used to. They span from
[-64, 64] now, but the texture itself is only valid within the [0, 1] range.
Recall from the last tutorial that the sampler object has a parameter that controls what texture coordinates outside of the [0, 1] range mean. This tutorial uses many samplers, but all of our samplers use the same S and T wrap modes:
glSamplerParameteri(g_samplers[samplerIx], GL_TEXTURE_WRAP_S, GL_REPEAT); glSamplerParameteri(g_samplers[samplerIx], GL_TEXTURE_WRAP_T, GL_REPEAT);
We set the S and T wrap modes to GL_REPEAT
. This means that values
outside of the [0, 1] range wrap around to values within the range. So a texture
coordinate of 1.1 becomes 0.1, and a texture coordinate of -0.1 becomes 0.9. The idea is
to make it as though the texture were infinitely large, with infinitely many copies
repeating over and over.
It is perfectly legitimate to set the texture coordinate wrapping modes differently for different coordinates. Well, usually; this does not work for certain texture types, but only because they take texture coordinates with special meanings. For them, the wrap modes are ignored entirely.
You may toggle between two meshes with the Y key. The alternative mesh is a long, square corridor.
The shaders used here are very simple. The vertex shader takes positions and texture coordinates as inputs and outputs the texture coordinate directly. The fragment shader takes the texture coordinate, fetches a texture with it, and writes that color value as output. Not even gamma correction is used.
The texture in question is 128x128 in size, with 4 alternating black and white squares on each side. Each of the black or white squares is 32 pixels across.